package main

import (
	"encoding/json"
	"fmt"
	"sort"
	"strconv"
	"strings"
)

// 点位描述结构体
type Point struct {
	Name       string `json:"name"`
	Label      string `json:"label"`
	AccessMode int    `json:"accessMode"`
	Type       int    `json:"type"`
	Params     struct {
		DbNumber  string `json:"dbNumber"`
		DataType  int    `json:"dataType"`
		StartAddr string `json:"startAddr"`
	} `json:"params"`
	Decimals int         `json:"decimals"`
	Unit     string      `json:"unit"`
	Value    interface{} `json:"value"`
}

// 地址转换函数
func parseAddress(addr string) (int, int) {
	parts := strings.Split(addr, ".")
	byteAddr, _ := strconv.Atoi(parts[0])
	bitAddr := 0
	if len(parts) > 1 {
		bitAddr, _ = strconv.Atoi(parts[1])
	}
	return byteAddr, bitAddr
}

// 合并点位逻辑
func mergePoints(points []Point, rangeLimit int) []Point {
	// 按 dbNumber 和地址排序
	sort.Slice(points, func(i, j int) bool {
		if points[i].Params.DbNumber == points[j].Params.DbNumber {
			addrI, _ := parseAddress(points[i].Params.StartAddr)
			addrJ, _ := parseAddress(points[j].Params.StartAddr)
			return addrI < addrJ
		}
		return points[i].Params.DbNumber < points[j].Params.DbNumber
	})

	merged := []Point{}
	for i := 0; i < len(points); i++ {
		if len(merged) >= rangeLimit {
			break // 达到读取限制
		}
		current := points[i]
		last := &merged[len(merged)-1]

		// 同一区间、连续地址合并
		if len(merged) > 0 && current.Params.DbNumber == last.Params.DbNumber {
			lastAddr, lastBit := parseAddress(last.Params.StartAddr)
			currentAddr, currentBit := parseAddress(current.Params.StartAddr)

			if currentAddr == lastAddr && currentBit == lastBit+1 {
				continue // 位连续不分割
			}
			if currentAddr == lastAddr+1 && currentBit == 0 && lastBit == 7 {
				continue // 字节连续
			}
		}
		merged = append(merged, current)
	}
	return merged
}

func main() {
	// 模拟 JSON 数据
	jsonData := `[...]` // 请将 JSON 数据粘贴到此处

	var points []Point
	if err := json.Unmarshal([]byte(jsonData), &points); err != nil {
		fmt.Println("JSON解析错误:", err)
		return
	}

	// 合并连续点位，设置读取限制为20
	mergedPoints := mergePoints(points, 20)

	// 输出合并结果
	for _, point := range mergedPoints {
		fmt.Printf("Name: %s, 区域: %s, 地址: %s\n", point.Name, point.Params.DbNumber, point.Params.StartAddr)
	}
}
